package org.miyuki4j.cfgtool;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import sun.misc.Signal;
import sun.misc.SignalHandler;

import java.util.Objects;

/**
 * @Desc
 * @Author miyuki4j
 * @Date 2025/7/28/星期一 17:59
 * @Version 1.0
 */

@SuppressWarnings({"SynchronizationOnLocalVariableOrMethodParameter", "SynchronizeOnNonFinalField"})
@Slf4j
public class CfgAppKeeper implements SignalHandler {

    static CfgAppKeeper INSTANCE = new CfgAppKeeper();

    @Getter
    @Setter
    private static CfgApp app;
    private static volatile boolean running = true;

    static void keep(CfgApp app) {
        Objects.requireNonNull(app, "app is null");
        CfgAppKeeper.app = app;
        registerSignalHandler();
        while (running) {
            synchronized (app) {
                try {
                    app.wait();
                } catch (InterruptedException ie) {
                    log.error("CfgAppKeeper.await interrupted.", ie);
                    break;
                }
            }
        }
        log.info("app keep finish.");
    }

    public synchronized static void done() {
        if (app == null) {
            return;
        }
        if (!running) {
            log.info("already done!!!");
            return;
        }
        log.info("✅ app {} done", app.getClass().getName());
        running = false;
        synchronized (app) {
            app.notify();
        }
    }

    @Override
    public void handle(Signal signal) {
        log.info("receive signal: {}", signal.getName());
        done();
    }

    public static void registerSignalHandler() {
        if (app.runMode() == RunModeEnum.GUI) {
            // gui 用界面关闭
            return;
        }
        // 捕获 Ctrl+C（SIGINT）
        Signal.handle(new Signal("INT"), INSTANCE);
        // 捕获 kill 命令（SIGTERM）
        Signal.handle(new Signal("TERM"), INSTANCE);
    }
}
